package ph.edu.upd.eee.upcatarchivesearch;

import android.util.Log;

import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import au.com.bytecode.opencsv.CSVReader;

/**
 * SearchArchive.java
 *
 * Methods for reading and parsing search results
 *
 * Created by smartwire on 10/3/2014.
 */
public class SearchArchive {
    public static final String TERM_SN = "termsn";
    public static final String TERM_NAME = "termname";

    private static Matcher mSN = null, mName = null;

    public ArrayList <SearchResult> readArchive(String terms, String path) {
        String termType;
        StringTokenizer javaSs;
        ArrayList <String> arrTerms = new ArrayList <String> ();
        ArrayList <SearchResult> resultSet = null;

        termType = getTermType(terms);

        if(termType.equals(TERM_SN)) {
            // Probably an SN search
            for(char c = 'A'; c <= 'Z'; c++) {
                resultSet = this.readArchiveSN(mSN.group(1) + "-" + mSN.group(2), mSN.group(1), path, c);
            }
        }
        else if(termType.equals(TERM_NAME)) {
            // Probably a name search
            // Isolate year
            terms = terms.substring(0, mName.start()) + terms.substring(mName.end(), terms.length());

            javaSs = new StringTokenizer(terms);

            while(javaSs.hasMoreTokens()) {
                arrTerms.add(javaSs.nextToken());
            }

            for(char c = 'A'; c <= 'Z'; c++) {
                resultSet = this.readArchiveName(arrTerms, mName.group(0), path, c);
            }
        }

        return resultSet;
    }

    public ArrayList <SearchResult> readArchiveSN(String terms, String year, String path, char letter) {
        String[] line;

        CSVReader csvIn = null;
        SearchResult result;
        ArrayList <SearchResult> resultSet = new ArrayList <SearchResult> ();
        try {
            // Hardcoded path from ZIP File
            csvIn = new CSVReader(new FileReader(path + "/" + year + "/upcat" + letter + ".csv"));

            while((line = csvIn.readNext()) != null) {
                if(line[0].contains(terms)) {
                    // Match first column for SN
                    result = new SearchResult(line);
                    result.upRelevance();

                    // Add to result set
                    resultSet.add(result);
                }
            }
        }
        catch(Exception e) {
            // Probably file doesn't exist
        }
        finally {
            try {
                if (csvIn != null) {
                    csvIn.close();
                }
            }
            catch(Exception e) {
                // Ignore me
            }
        }

        // Sort by increasing relevance
        Collections.sort(resultSet, Collections.reverseOrder());

        return resultSet;
    }

    public ArrayList <SearchResult> readArchiveName(ArrayList <String> arrTerms, String year, String path, char letter) {
        String[] line;

        StringTokenizer javaSs;
        CSVReader csvIn = null;
        SearchResult result;
        ArrayList <SearchResult> resultSet = new ArrayList <SearchResult> ();

        try {
            // Hardcoded path from ZIP File
            csvIn = new CSVReader(new FileReader(path + "/" + year + "/upcat" + letter + ".csv"));

            while((line = csvIn.readNext()) != null) {
                // Match each entry in second column for name
                result = new SearchResult(line);

                javaSs = new StringTokenizer(line[1], " ,"); // Entry terms

                while(javaSs.hasMoreTokens()) {
                    String sr = javaSs.nextToken();

                    for(String s : arrTerms) {
                        if(s.equalsIgnoreCase(sr)) {
                            result.upRelevance();
                        }
                    }
                }

                if(result.getRelevance() > 0) {
                    // Add to result set
                    resultSet.add(result);
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (csvIn != null) {
                    csvIn.close();
                }
            }
            catch(Exception e) {
                // Ignore me
            }
        }

        // Sort by increasing relevance
        Collections.sort(resultSet, Collections.reverseOrder());

        return resultSet;
    }

    public static String getTermType(String terms) {
        Pattern pSN, pName;

        pSN = Pattern.compile("^([12][0-9]{3})-?([0-9]{5})$", Pattern.CASE_INSENSITIVE);
        pName = Pattern.compile("#([12][0-9]{3})", Pattern.CASE_INSENSITIVE);

        // Predict search terms
        mSN = pSN.matcher(terms);
        mName = pName.matcher(terms);

        if(mSN.find()) {
            return SearchArchive.TERM_SN;
        }
        else if(mName.find()) {
            return SearchArchive.TERM_NAME;
        }

        return null;
    }

    public Matcher getSNMatcher() {
        return mSN;
    }

    public Matcher getNameMatcher() {
        return mName;
    }
}
